/*jshint esversion: 9 */
/*
 *简单的回调类型请求工具
 *XMLHttpRequest官方文档 https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest
 *responseType枚举值 https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/responseType
 */
export function stringToJson(str) {  //string 转 json 对象
    try {
        let target = JSON.parse(str);
        if (typeof target == "object") {
            return target;
        }
    } catch(e) {
        console.error(e);
        return str;
    }
}
export function checkURL(url){  //检查是否是一个完整的URL
    var exp=new RegExp(/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\\/?%&=]*)?/);
    return exp.test(url);
}
export function createHttp(){  //创造一个请求
    return new XMLHttpRequest(); 
}
export function addEventListener({
    target,async,
    readyStateChange,
    loadStart,
    uploadProgress,
    progress,
    abort,
    error,
    load,
    timeOut,
    loadend,
}){  //添加事件
    target.addEventListener(  //下载进度
        "readystatechange", 
        (e)=>readyStateChange && readyStateChange(target,e),
    );
    target.upload.addEventListener(  //上传进度
        "progress",
        (e)=>uploadProgress && uploadProgress(target,e),
    );
    target.addEventListener(  //下载进度
        "progress",
        (e)=>progress && progress(target,e),
    );
    target.addEventListener(
        "load",
        (e)=>load && load(target,e),
    );
    target.addEventListener(
        "error",
        (e)=>error && error(target,e),
    );
    target.addEventListener(
        "abort",
        (e)=>abort && abort(target,e),
    );
    target.addEventListener(
        "loadstart", 
        (e)=>loadStart && loadStart(target,e),
    );
    target.addEventListener(
        "loadend",
        (e)=>loadend && loadend(target,e),
    );
    if(async){  //异步才添加超时
        target.addEventListener(
            "timeout",
            (e)=>timeOut && timeOut(target,e),
        );
    }
}
export function setRequestHeaders({
    headers={},
    target={},
}){  //写入请求头
    for(let index in headers){
        target.setRequestHeader(index,headers[index]);
    }
    return target;
}
export class EasyHttp{
    constructor({
        timeOut=130000,  //超时时间
        baseUrl='',  //公共根路径（url不全时会自动拼接）
        responseType='',  //公共的返回数据类型
    }={}){
        this.timeOut = timeOut;
        this.baseUrl = baseUrl;
        this.responseType = responseType;
        this.intercept = {  //拦截器
            request:{
                success:undefined,
                error:undefined,
            },
            response:{
                success:undefined,
                error:undefined,
            },
        };
    }
    setRequestIntercept(success,error){  //写入请求拦截器
        this.intercept.request.success = success;
        this.intercept.request.error = error;
    }
    setResponseIntercept(success,error){  //写入返回数据拦截器(必须手动调用成功或失败回调)
        this.intercept.response.success = success;
        this.intercept.response.error = error;
    }
    createRequest({  //创建请求
        url='',params={},async=true,withCredentials,method,responseType,headers={},
        success=()=>{},
        error=()=>{},
        progress=()=>{},
        uploadProgress=()=>{},
        loadend=()=>{},
        abort,
        load,
        timeOut,
    }={}){
        try{
            let xhr = createHttp();
            xhr.open(
                method ? method.toUpperCase() : 'GET',
                checkURL(url)?url:(this.baseUrl + url),
                async,
            );
            addEventListener({
                target:xhr,
                async,
                uploadProgress,
                progress,
                loadend,
                abort,
                load,
                timeOut,
                readyStateChange:()=>{
                    if(xhr.readyState !== 4) return;
                    if(xhr.status === 200) {  //请求成功正确
                        if(this.intercept.response.success){
                            this.intercept.response.success({
                                target:xhr,
                                method,
                                success,
                                error,
                            });
                        }else{
                            success(xhr);
                        }
                    } else {  //请求失败
                        if(this.intercept.response.error){
                            this.intercept.response.error({
                                target:xhr,
                                method,
                                success,
                                error,
                            });
                        }else{
                            error(xhr);
                        }
                    }
                },
            });
            setRequestHeaders({
                target:xhr,
                headers:headers,
            });
            if(async){  //异步才添加超时
                xhr.timeout = this.timeOut;
                xhr.responseType = responseType || this.responseType || xhr.responseType;  //返回数据类型(优先使用请求参数)
            }
            xhr.withCredentials = withCredentials;  //指示是否应使用Cookie或授权标头等凭据进行跨站点访问控制请求。
            if(this.intercept.request.success){   //请求拦截
                xhr = this.intercept.request.success(xhr) || xhr;
            }
            xhr.send(params || null);
            return xhr;
        }catch(e){
            if(this.intercept.request.error){  //请求拦截
                this.intercept.request.error(e);
            }
            return undefined;
        }
    }
    get(option){
        return this.createRequest({
            ...option,
            method:'get',
        });
    }
    post(option){
        return this.createRequest({
            ...option,
            method:'post',
        });
    }
    put(option){
        return this.createRequest({
            ...option,
            method:'put',
        });
    }
    delete(option){
        return this.createRequest({
            ...option,
            method:'delete',
        });
    }
}
/*
 *test 测试
 */
// let a = new EasyHttp({
//     timeOut:10000,
//     baseUrl:'',
//     responseType:'json',
// });
// a.setRequestIntercept(  //请求拦截器
//     (target)=>{
//         target.setRequestHeader(
//             'test',
//             new Date().getTime(),
//         );
//         return target;
//     },
//     (e)=>{
//         console.log('请求发生错误--');
//         throw e;
//     },
// );
// a.setResponseIntercept(  //返回数据拦截器
//     ({target,success,error})=>{
//         let data = target.response;
//         if(data && data.state == 200){
//             success(data);
//         }else{
//             error(data);
//         }
//     },
//     ({e,error})=>{
//         console.log('请求发生错误了');
//         error(e);
//     },
// );
// a.post({
//     url:'http://localhost:8080/api/app0/policy?page=1&size=7&title=&area=&origin=&state=%E7%94%B3%E6%8A%A5%E4%B8%AD&total=69&other=%7B%22t%22:%22%22%7D',
//     params:JSON.stringify({a:1}),
//     headers:{
//         "Content-Type":"application/json;charset=UTF-8",
//     },
//     success({data}){
//         console.log('返回数据');
//         console.log(data);
//     },
//     error(e){
//         console.log('返回数据1');
//         console.log(e);
//     },
//     uploadProgress(x,e){
//         console.log(1);
//         console.log(e);
//     },
// });